<?php
require_once '../prepend.php';
require_once 'Zend/Loader.php';
class State{
	private $id, $title,$transition;

	public function __construct($id, $title, Transition $transition){
		$this->id = $id;
		$this->title = $title;
		$this->transition = $transition;
	}

	public function __toString(){
		return "The State: ".(string)$this->id."<br>Title:".(string)$this->title .
		" <br><i>has this transition: " . $this->transition->getName() . "</i>";
	}
}
class Transition{
	private $id, $desc;

	public function __construct($id, $desc){
		$this->id = $id;
		$this->desc = $desc;
	}
	public function getName(){return $this->id;}
	public function __toString(){
		return "The Transition: ".(string)$this->id."<br>Desc:".(string)$this->title;
	}
}
interface IClassDefinition{
	public function __construct(Array $arDef);
	function check(Array $arDef);
}
class ClassDefinition implements IClassDefinition {
	public $name, $path, $args, $require_once=true;

	public function __construct(Array $arDef){
		$this->check($arDef);
		
		$this->name = $arDef['name'];
		$this->args = $arDef['args'];
		$this->path = $arDef['path'];
		$this->require_once = $arDef['require_once'];
	}
	
	private function check(Array $arDef){
		if(!array_key_exists('name', $arDef) &&
		   !array_key_exists('args', $arDef) &&
		   !array_key_exists('path', $arDef) &&
		   !array_key_exists('require_once', $arDef)){
		   	throw new MException('Array is not VALID!');
		   }
	}
}
abstract class AFactory{

	public static function instance(){}
}
class ConcreteFactory extends AFactory
{
	public static function instance(IClassDefinition $CD){
		try {
			Zend_Loader::loadClass($CD->name, $CD->path);
			//Zend_Loader::loadFile($class['name'].'.php', $path, $require_once);
		} catch (Zend_Exception $ze){
			echo $ze->getMessage();
			exit;
		}
		//get the class properties
		$class_ = new ReflectionClass($CD->name);

		return $class_->newInstanceArgs($CD->args);
	}
}
class Factory extends AFactory
{
	// The parameterized factory method
	public static function instance(Array $class)
	{
		try {
			Zend_Loader::loadClass($class['name'], $class['path']);
			//Zend_Loader::loadFile($class['name'].'.php', $path, $require_once);
		} catch (Zend_Exception $ze){
			echo $ze->getMessage();
			exit;
		}
			
		//get the class properties
		$class_ = new ReflectionClass($class['name']);

		$obj = $class_->newInstanceArgs($class['args']);

		//return new $className();
		return $obj;
	}
}

$arClass = array("name" => "State",
"path" => null,
"require_once" => true,
"args" => array("published", "Published Content", new Transition('publish', 'To Publish the content.')));

$O_cd = new ClassDefinition($arClass);

echo "<hr>1o.<br>";
try{
	$state = Factory::instance($arClass);
	echo $state;
}catch (Exception $e){
	echo $e->getMessage();
}
echo "<br><hr>2o.<br>";
try{
	$state = ConcreteFactory::instance($O_cd);
	echo $state;
}catch (Exception $e){
	echo $e->getMessage();
}
echo "<br><hr>3o.<br>";
$st = new State('hide', 'Hide the content!',new Transition('publish33', 'To Publish the content33.'));
echo $st;
?>